Skip to content

feat: add session.getMetadata to all SDK languages#899

Open
MackinnonBuck wants to merge 5 commits intomainfrom
add-get-session-metadata
Open

feat: add session.getMetadata to all SDK languages#899
MackinnonBuck wants to merge 5 commits intomainfrom
add-get-session-metadata

Conversation

@MackinnonBuck
Copy link
Collaborator

Motivation

The runtime now exposes a session.getMetadata JSON-RPC method (copilot-agent-runtime#5021) that provides efficient O(1) lookup of a single session's metadata by ID — avoiding the need to call session.list and filter client-side. This PR exposes that endpoint in all four SDK language bindings.

Approach

Each SDK already has listSessions returning SessionMetadata[]. The new method reuses the same SessionMetadata type (no new public types needed) but returns a single optional result. When the session is not found, the method returns the language-idiomatic "absent" value rather than throwing an error.

SDK Method Return type Not-found value
Node.js getSessionMetadata(sessionId) Promise<SessionMetadata | undefined> undefined
Python get_session_metadata(session_id) SessionMetadata | None None
Go GetSessionMetadata(ctx, sessionID) (*SessionMetadata, error) nil
.NET GetSessionMetadataAsync(sessionId, ct) Task<SessionMetadata?> null

Changes

  • Node.js — New method in client.ts with full JSDoc; skipped E2E test (matching existing listSessions skip pattern)
  • Python — New method in client.py with docstring; running E2E test (Python/Go session lifecycle tests are live)
  • Go — New method in client.go, internal request/response structs in types.go; running E2E test
  • .NET — New method in Client.cs, internal records + [JsonSerializable] registration; skipped E2E test
  • Snapshottest/snapshots/session/should_get_session_metadata.yaml for the replay proxy

Notes

  • E2E tests in Node.js and .NET are skipped with the same TODO as the existing listSessions tests ("Re-enable once test harness CAPI proxy supports this test's session lifecycle"). Python and Go E2E tests are running, consistent with their existing session lifecycle tests.
  • All E2E tests cover both the happy path (create session → get metadata → verify fields) and the not-found case.

Add a new getSessionMetadata method across all four SDK language bindings
(Node.js, Python, Go, .NET) that provides efficient O(1) lookup of a
single session's metadata by ID via the session.getMetadata JSON-RPC
endpoint.

Changes per SDK:
- Node.js: getSessionMetadata() in client.ts + skipped E2E test
- Python: get_session_metadata() in client.py + running E2E test
- Go: GetSessionMetadata() in client.go + types in types.go + running E2E test
- .NET: GetSessionMetadataAsync() in Client.cs + skipped E2E test

Also adds test/snapshots/session/should_get_session_metadata.yaml for
the E2E test replay proxy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review

I've reviewed this PR for consistency across all four SDK implementations (Node.js, Python, Go, and .NET). This PR maintains excellent cross-language consistency!

Summary

This PR successfully adds the session.getMetadata RPC method to all four SDK languages with consistent:

API Design

  • Node.js: getSessionMetadata(sessionId)Promise(SessionMetadata | undefined)
  • Python: get_session_metadata(session_id)SessionMetadata | None
  • Go: GetSessionMetadata(ctx, sessionID)(*SessionMetadata, error)
  • .NET: GetSessionMetadataAsync(sessionId, ct)Task(SessionMetadata?)

All follow language-specific naming conventions (camelCase, snake_case, PascalCase) and return idiomatic "not found" values (undefined, None, nil, null).

Implementation Pattern

  • All SDKs reuse the existing SessionMetadata type (no new types needed)
  • All call the same JSON-RPC method: session.getMetadata
  • All properly check client connection state before making the call
  • All handle the not-found case gracefully without throwing errors

Documentation

  • Consistent descriptions across all languages emphasizing O(1) efficiency
  • Similar code examples demonstrating usage
  • Proper parameter and return type documentation

Test Coverage

  • Node.js and .NET: Tests present but skipped (matching existing listSessions pattern with same TODO)
  • Python and Go: Active E2E tests (consistent with their existing session lifecycle test patterns)
  • All tests cover both success and not-found cases
  • Shared snapshot file: test/snapshots/session/should_get_session_metadata.yaml

No Consistency Issues Found

This PR maintains feature parity and consistent API design across all SDK implementations. Great work! 🎉

Generated by SDK Consistency Review Agent for issue #899 ·

@SteveSandersonMS
Copy link
Contributor

@MackinnonBuck Looks like this is close to being ready. If you're waiting for review please let me know, but otherwise I'll hold off until the Go part is passing.

@MackinnonBuck MackinnonBuck marked this pull request as ready for review March 24, 2026 20:21
@MackinnonBuck MackinnonBuck requested a review from a team as a code owner March 24, 2026 20:21
Copilot AI review requested due to automatic review settings March 24, 2026 20:21
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review

This PR demonstrates excellent cross-language consistency. The getSessionMetadata feature has been implemented uniformly across all four SDK languages with appropriate language idioms.

API Consistency ✓

All four SDKs follow the same semantic pattern:

SDK Method Name Return Type Not-Found Value
Node.js getSessionMetadata(sessionId) Promise(SessionMetadata | undefined) undefined
Python get_session_metadata(session_id) SessionMetadata | None None
Go GetSessionMetadata(ctx, sessionID) (*SessionMetadata, error) nil
.NET GetSessionMetadataAsync(sessionId, ct) Task(SessionMetadata?) null

Naming conventions: Properly adapted to each language (camelCase, snake_case, PascalCase)
Return types: Correctly use language-idiomatic optional/nullable patterns
Parameters: Consistent parameter naming (sessionId/session_id/sessionID)
Type reuse: All implementations reuse the existing SessionMetadata type

Documentation Consistency ✓

All four implementations include:

  • Clear method summaries describing the O(1) lookup behavior
  • Parameter documentation
  • Return value documentation
  • Exception/error handling notes
  • Code examples showing usage

Test Coverage Consistency ✓

All four SDKs include E2E tests that:

  • Create a session and verify metadata can be retrieved
  • Verify the returned fields (sessionId, startTime, modifiedTime)
  • Test the not-found case (returns undefined/None/nil/null)

Test status is correctly aligned with existing listSessions patterns:

  • Node.js & .NET: Skipped with TODO comment (matching listSessions)
  • Python & Go: Running tests (matching listSessions)

Implementation Details ✓

  • All SDKs call the same JSON-RPC method: "session.getMetadata"
  • Request/response structures are properly defined as internal types
  • Error handling follows each SDK's established patterns
  • Snapshot test added: test/snapshots/session/should_get_session_metadata.yaml

No consistency issues found. This PR maintains excellent feature parity across the SDK implementations. 🎉

Generated by SDK Consistency Review Agent for issue #899 ·

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Exposes the new session.getMetadata JSON-RPC endpoint across all four SDKs to enable efficient per-session metadata lookup without calling session.list and filtering client-side.

Changes:

  • Added session metadata lookup methods to Node, Python, Go, and .NET clients with language-idiomatic “not found” results.
  • Added/updated E2E coverage (running in Python/Go; skipped in Node/.NET to match existing patterns).
  • Added a replay-proxy snapshot for the new session metadata E2E scenario.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/snapshots/session/should_get_session_metadata.yaml Adds replay-proxy snapshot used by the new session-metadata E2E scenario.
python/e2e/test_session.py Adds a running E2E test covering happy-path + not-found behavior for get_session_metadata.
python/copilot/client.py Implements get_session_metadata(session_id) returning `SessionMetadata
nodejs/test/e2e/session.test.ts Adds a skipped E2E test for getSessionMetadata (consistent with existing skipped lifecycle tests).
nodejs/src/client.ts Implements getSessionMetadata(sessionId) returning SessionMetadata | undefined.
go/types.go Adds internal request/response structs for session.getMetadata.
go/internal/e2e/session_test.go Adds a running E2E subtest for GetSessionMetadata happy-path + not-found.
go/client.go Implements GetSessionMetadata(ctx, sessionID) returning (*SessionMetadata, error) with nil for not-found.
dotnet/test/SessionTests.cs Adds a skipped test for GetSessionMetadataAsync happy-path + not-found.
dotnet/src/Client.cs Implements GetSessionMetadataAsync, adds internal request/response records, and registers them for source-gen JSON.

- Fix Python copilot/client.py ruff format check by collapsing
  get_session_metadata method signature and request call to single lines
- Fix Node.js session.test.ts assertion to check first message only,
  since CLI 1.0.11 now emits session.custom_agents_updated after
  session.start (matching the same fix needed on main)
CLI 1.0.11 makes a GET request to /agents/*/custom-agents/* during
startup. The replay proxy had no handler for this endpoint, causing
it to call onError and hang new CLI processes. This broke the
'should resume a session using a new client' and 'should produce
deltas after session resume' E2E tests which spawn a second
CopilotClient.

Add a stub handler (returning empty agents list) matching the
existing pattern used for memory endpoints.
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review

This PR demonstrates excellent consistency across all four SDK implementations. The getSessionMetadata / get_session_metadata / GetSessionMetadata feature has been implemented uniformly:

API Design Consistency ✨

All four SDKs follow parallel patterns accounting for language idioms:

SDK Method Name Return Type Not-found Value
Node.js getSessionMetadata(sessionId) Promise(SessionMetadata | undefined) undefined
Python get_session_metadata(session_id) SessionMetadata | None None
Go GetSessionMetadata(ctx, sessionID) (*SessionMetadata, error) nil
.NET GetSessionMetadataAsync(sessionId, ct) Task(SessionMetadata?) null

Key Consistency Points ✅

  1. RPC endpoint: All use "session.getMetadata"
  2. Request structure: { sessionId: string } across all languages ✅
  3. Response structure: { session?: SessionMetadata }
  4. Not-found behavior: Returns language-idiomatic "absent" value (no errors thrown) ✅
  5. Documentation: All have comprehensive docs with O(1) performance note ✅
  6. E2E tests: All languages have tests covering:
    • Happy path (create session → get metadata → verify fields)
    • Not-found case (non-existent session returns null/nil/None/undefined)
    • Python/Go tests are running
    • Node.js/.NET tests are skipped with consistent TODO comment ✅

Implementation Quality 🎯

  • Node.js extracted a shared toSessionMetadata helper for DRY code
  • Python reuses SessionMetadata.from_dict
  • Go properly defines internal request/response structs
  • .NET correctly registers types with [JsonSerializable]

No consistency issues found. This is a model example of feature parity across the SDK! 🚀

Generated by SDK Consistency Review Agent for issue #899 ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants